package com.mew.chess.core.game.yxx.game;

import com.mew.chess.core.game.yxx.game.common.YxxConstantValue;
import com.mew.chess.core.game.yxx.game.common.YxxLinkType;
import com.mew.chess.core.game.yxx.game.task.*;
import com.mew.common.config.SpringContextBean;
import com.zebra.common.concurrent.ZebraScheduler;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;


@Data
@ToString(of = {"roomId"})
@NoArgsConstructor
@Slf4j
public class YxxScheduleManager {
    private AtomicBoolean flag = new AtomicBoolean(false);

    private int roomId;

    private ZebraScheduler zebraScheduler;
    private ExecutorService executorService;

    private ScheduledFuture<?> scheduledFuture;
    private ScheduledFuture<?> scheduledFutureCycle;

    private YxxPreparTask preparTask;
    private YxxStartBetTask startBetTask;
    private YxxDealCardTask dealCardTask;
    private YxxPaymentTask paymentTask;
    private YxxPushBetScheduleTask pushBetScheduleTask;

    public YxxScheduleManager(int roomId, ZebraScheduler zebraScheduler, ExecutorService executorService){
        this.roomId = roomId;
        this.zebraScheduler = zebraScheduler;
        this.executorService = executorService;
    }

    private void initializeTask(){
        if (null == preparTask){
            preparTask = SpringContextBean.getBean(YxxPreparTask.class);
        }
        if (null == startBetTask){
            startBetTask = SpringContextBean.getBean(YxxStartBetTask.class);
        }
        if (null == pushBetScheduleTask){
            pushBetScheduleTask = new YxxPushBetScheduleTask();
        }


        if (null == dealCardTask){
            dealCardTask = SpringContextBean.getBean(YxxDealCardTask.class);
        }
        if (null == paymentTask){
            paymentTask = SpringContextBean.getBean(YxxPaymentTask.class);
        }


    }

    public void start(){
        if(flag.compareAndSet(false, true)){
            initializeTask();
            prepareStartTimer();
        }
    }

    public void stop(){
        zebraScheduler.cancelScheduled(scheduledFuture);
        flag.getAndSet(false);
    }

    //游戏初始化准备
    private void prepareStartTimer(){
        log.info("---Yxx Prepare StartTimer：roomId {}", this.getRoomId());
        YxxRoomManager roomManager =  YxxGameManager.getInstance().getController(roomId);
        roomManager.setLinkType(YxxLinkType.Prepare.code());
        roomManager.setStartTime(System.currentTimeMillis());
        roomManager.setRuleTime(YxxConstantValue.PREPARE_TIME);
        scheduledFuture = zebraScheduler.schedule((this::startTimer), YxxConstantValue.PREPARE_TIME, TimeUnit.MILLISECONDS, executorService);
    }

    //开始前准备阶段
    private void prepareTimer(){
        preparTask.startPrepar(roomId);
        scheduledFuture = zebraScheduler.schedule((this::startTimer), YxxConstantValue.PREPARE_TIME, TimeUnit.MILLISECONDS, executorService);
    }

    //开始阶段
    private void startTimer(){

        if (!startBetTask.startBet(roomId)){
            return;
        }
        log.info("---Yxx Start roomId {}", roomId);
        scheduledFutureCycle = zebraScheduler.scheduleWithFixedDelay((this::doCycleRobotBet), 600L, YxxConstantValue.PLAY_PUSH, TimeUnit.MILLISECONDS, executorService);
        scheduledFuture = zebraScheduler.schedule((this::doDealCard), YxxConstantValue.START_TIME, TimeUnit.MILLISECONDS, executorService);

    }

    //机器人押注
    private void doCycleRobotBet(){
        pushBetScheduleTask.robotBet(roomId, scheduledFutureCycle);
    }

    //发牌
    private void doDealCard(){
        log.info("---Yxx doDealCard roomId {}", roomId);
        zebraScheduler.cancelScheduled(scheduledFutureCycle);
        dealCardTask.dealCard(roomId);
        scheduledFuture = zebraScheduler.schedule((this::doPayment), YxxConstantValue.DEAL_TIME, TimeUnit.MILLISECONDS, executorService);
    }


    //赔付
    private void doPayment(){
        log.info("---Yxx doPayment roomId {}", roomId);
        paymentTask.payment(roomId);
        scheduledFuture = zebraScheduler.schedule((this::prepareTimer), YxxConstantValue.PAYMENT_TIME, TimeUnit.MILLISECONDS, executorService);
    }




}
